package com.lll.simple.rpc.protocol.encoder;

import com.lll.simple.rpc.common.MessageHeader;
import com.lll.simple.rpc.common.RpcProtocol;
import com.lll.simple.rpc.protocol.serialization.RpcSerialization;
import com.lll.simple.rpc.protocol.serialization.SerializationFactory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;

/**
 * @Author: liull
 * @Description: 编码器(出站处理器)，对于客户端用来编码RpcRequest,服务端用来编码RpcResponse
 * @Date: Created in 10:33 2021/2/4
 * @Modified By:
 * +---------------------------------------------------------------+
 *
 * | 魔数 2byte | 协议版本号 1byte | 序列化算法 1byte | 报文类型 1byte  |
 *
 * +---------------------------------------------------------------+
 *
 * | 状态 1byte |        消息 ID 8byte     |      数据长度 4byte     |
 *
 * +---------------------------------------------------------------+
 *
 * |                   数据内容 （长度不定）                          |
 *
 * +---------------------------------------------------------------+
 */
public class RpcEncoder extends MessageToByteEncoder<RpcProtocol<Object>> {
    @Override
    protected void encode(ChannelHandlerContext ctx, RpcProtocol<Object> msg, ByteBuf out) throws Exception {
        MessageHeader header = msg.getHeader();
        Object body = msg.getBody();
        out.writeShort(header.getMagic());
        out.writeByte(header.getVersion());
        out.writeByte(header.getSerialization());
        byte msgType = header.getMsgType();
        out.writeByte(msgType);
        out.writeByte(header.getStatus());
        out.writeLong(header.getRequestId());
        RpcSerialization serialization = SerializationFactory.getSerializationByType(header.getSerialization());
        byte[] bytes = serialization.serialize(body);
        out.writeInt(bytes.length);
        out.writeBytes(bytes);
    }
}
